//
//  STDSLutEffect.h
//  STDSRenderSDKIOS
//
//  Created by 陈学明 on 2023/10/25.
//

#ifndef STDSLutEffect_h
#define STDSLutEffect_h

#include "STDSBaseEffect.hpp"
// 仿制图章工具

class STDSLutEffect: public STDSBaseEffect {
public:
    STDSLutEffect() {
        mEffectType = STDSEffectTypeLut;
    }
    ~STDSLutEffect() {
//        printf("dealloc--STDSMosaicEffect\n");
    }
    
    void initGL() override {
        STDSBaseEffect::initGL();
    }
    
    void setFloatArguments(const char *name, float *floatValue, int n) override {
        if (strcmp(name, "alpha") == 0) {
            mAlpha = *floatValue;
        }
    }
    
    void setStringArtuments(const char *name, const char *stringValue) override {
        if (strcmp(name, "lut") == 0) {
            auto lut_path = std::string(stringValue);
            this->mContext->autoRelease(this->mLut);
            this->mLut = this->mContext->getImageTexture(lut_path);
        }
    }
    
    void setBitmapArguments(const char *name, const char *data, int width, int height) override {
        if (strcmp(name, "lut") == 0) {
            this->mContext->autoRelease(this->mLut);
            this->mLut = make_shared<STDSTexture>((const unsigned char *)data, width, height);
        }
    }
    
public:
    shared_ptr<STDSShaderProgram> getLutProgram() {
        if (mLutProgram == nullptr) {
            mLutProgram = mContext->getProgram(kShaderSRCLut);
        }
        return mLutProgram;
    }

    // 绘制
    void draw() override {
        auto lutProgram = getLutProgram();

        if (lutProgram == nullptr || mTexture == nullptr) {
            return;
        }
        if (mLut == nullptr) {
            drawTexture(mTexture->getId());
            return;
        }
        lutProgram->use();
        if (mTexture != nullptr) {
            glActiveTexture(GL_TEXTURE0);
            glBindTexture(GL_TEXTURE_2D, mTexture->getId());
            lutProgram->setUniform(lutProgram->getUniform("uTexture"), 0);
        }
        
        if (mLut != nullptr) {
            glActiveTexture(GL_TEXTURE1);
            glBindTexture(GL_TEXTURE_2D, mLut->getId());
            lutProgram->setUniform(lutProgram->getUniform("uLut"), 1);
        }
        lutProgram->setUniform(lutProgram->getUniform("uAlpha"), mAlpha);
        lutProgram->setUniform2f(lutProgram->getUniform("uSize"), mSizeSRC.x, mSizeSRC.y);
        
        mAtbRect.setPosVex(lutProgram->getAttrib("aPos"));
        mAtbRect.setPosTex(lutProgram->getAttrib("aTexCoord"));
        mAtbRect.draw();
        lutProgram->unuse();
    }

private:
    shared_ptr<STDSTexture> mLut{nullptr}; // lut
    shared_ptr<STDSShaderProgram> mLutProgram{nullptr}; // 仿射变换着色器
    float mAlpha{0.4};
    
};

#endif /* STDSLutEffect_h */
